//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "iwdg_bsp.h"
#include "gd32f4xx_fwdgt.h"


/*看门狗互斥锁*/
static volatile FlagStatus WHT_IWDG_Mutex = RESET;


/*看门狗喂狗*/
static void WHT_IWDG_BSP_Feed_Dog(void)
{
    if (WHT_IWDG_Mutex == RESET)
        fwdgt_counter_reload();  //重装载到 IWDG 计数器
}
/*看门狗启动*/
static void WHT_IWDG_BSP_Start(void)
{
    if (WHT_IWDG_Mutex == RESET)
    {
        WHT_IWDG_BSP_Feed_Dog();
        fwdgt_enable();         //使能 IWDG
    }
}
/*看门狗复位重装载*/
static ErrStatus WHT_IWDG_BSP_Reset_Reload(unsigned int reset_time_ms)
{
    unsigned short IWDG_Reload_Value;
    unsigned short IWDG_Div_Value;
    
    if ((reset_time_ms > WHT_IWDG_BSP_MAX_RESET_TIME_MS) || (reset_time_ms == 0))
        return ERROR;
    else
    {
        IWDG_Div_Value = 0x01 << (32 - __clz(reset_time_ms / (unsigned int)(409.6 / 4)));
        WHT_IWDG_Mutex = SET;
        while(fwdgt_flag_get(FWDGT_STAT_RUD) != RESET);//wait RVU idle
        fwdgt_write_enable();//使能对预分频和重装载寄存器的访问 
        switch (IWDG_Div_Value)
        {
        case 1:
        case 2:
        case 4:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV4);          //设置 IWDG 预分频值
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 4.0f;
            break;
        case 8:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV8);
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 8.0f;
            break;
        case 16:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV16); 
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 16.0f;
            break;
        case 32:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV32); 
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 32.0f;
            break;
        case 64:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV64);
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 64.0f;
            break;
        case 128:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV128);
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 128.0f;
            break;
        case 256:
        case 512:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV256);
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 256.0f;
            break;
        default:
            fwdgt_prescaler_value_config(FWDGT_PSC_DIV256);
            IWDG_Reload_Value = reset_time_ms  * (WHT_IWDG_BSP_LSI_CLK_HZ / 1000) / 256.0f;
            break;
        }
        fwdgt_reload_value_config(IWDG_Reload_Value);                //设置 IWDG 重装载值，注意不能大于0xfff
        WHT_IWDG_BSP_Feed_Dog();
        WHT_IWDG_Mutex = RESET;
        return SUCCESS;
    }
}


/*全局常量*/
const WHT_IWDG_BSP_t WHT_IWDG_BSP =
{
    .WHT_Start        = WHT_IWDG_BSP_Start,
    .WHT_Stop         = ((void *)0),
    .WHT_Feed_Dog     = WHT_IWDG_BSP_Feed_Dog,
    .WHT_Reset_Reload = WHT_IWDG_BSP_Reset_Reload,
};
